package cate.common.table;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public abstract class EExcel {

    /** 获取文件名，比如 XXX.xlsx */
    abstract public String getFileName();

    abstract public ESheet[] getSheets();

    private EContext context;

    public void setContext(EContext context) {
        this.context = context;
    }

    public EContext getContext() {
        if(this.context == null) {
            this.context = new EContextDefaultImpl();
        }
        return this.context;
    }

    /**
     * @return 表是否存在
     */
    public boolean load() {
        File file = context.getFile(getFileName());
        try {
            Map<String, XSSFSheet> xsMap = new HashMap<>();
            if(!file.exists()) {
                file = context.getFile("$" + getFileName());//客户端不关注的表会添加$标注
                if(!file.exists()) {
                    this.getContext().errorOnFileNotExist(getFileName(), file);
                    return false;
                }
            }
            FileInputStream fis = new FileInputStream(file);
            XSSFWorkbook workbook = new XSSFWorkbook(fis);
            final int sheetNum = workbook.getNumberOfSheets();
            for(int i = 0; i < sheetNum; i++) {
                XSSFSheet xs = workbook.getSheetAt(i);
                xsMap.put(xs.getSheetName(), xs);
            }
            for(ESheet sheet : getSheets()) {
                XSSFSheet xs = xsMap.get(sheet.getSheetName());
                if(xs == null) {
                    xs = xsMap.get("$"+sheet.getSheetName());
                    if(xs == null) {
                        this.getContext().errorOnSheetNotExist(sheet.getSheetName());
                        continue;
                    }
                }
                sheet.parent = this;
                try {
                    XSSFRowWrap.setCurrentSheet(""+this.getFileName()+"/"+sheet.getSheetName());
                    sheet.load(xs);
                    XSSFRowWrap.setCurrentSheet("");
                } catch (Exception e) {
                    this.getContext().errorOnSheetLoading(sheet.getSheetName(), e);
                }
            }
            workbook.close();
        } catch (Exception e) {
            log.error("", e);
        }
        return true;
    }

    public void decode() {
        for(ESheet sheet : getSheets()) {
            try {
                sheet.decode();
            } catch (Exception e) {
                this.getContext().errorOnSheetDecoding(sheet.getSheetName(), e);
            }
        }
    }

}
